<?php

namespace app\common\service\learn;

use app\common\enums\ArticleStatusEnum;
use app\common\enums\CourseDataTypeEnum;
use app\common\enums\CourseDictTypeEnum;
use app\common\enums\LearnMeansEnum;
use app\common\enums\ReadingTypeEnum;
use app\common\model\banxi\learn\LearnReading;
use app\common\model\banxi\learn\LearnSkRecord;
use app\common\model\banxi\learn\LearnReadingArticle;
use app\common\model\banxi\learn\LearnReadingArticleExtend;
use app\common\model\banxi\learn\LearnReadingArticleAnswer;
use app\common\model\banxi\learn\LearnReadingArticleMarkWord;
use app\common\model\banxi\course\CourseArticle;
use app\common\model\banxi\student\Student;
use app\common\model\banxi\course\CourseQuestion;
use app\common\service\ApiService;
use ba\Exception;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\facade\Db;

class LearnReadingArticleService extends ApiService
{
    /**
     * 开始阅读处理过程
     * @param int|null $skRecordId 上课记录ID
     * @param int|null $studentId 学生ID
     * @param int|null $trainerId 教练ID
     * @param int $articleId 文章ID
     * @param int $learnMeans 学习方式（1-教学，2-练习）
     * @return int 阅读记录ID
     * @throws Exception
     */
    public function startReading($skRecordId, $studentId, $trainerId, $articleId, $learnMeans)
    {
//        var_dump('$skRecordId:'.$skRecordId);
//        var_dump('$studentId:'.$studentId);
//        var_dump('$trainerId:'.$trainerId);
//        var_dump('$articleId:'.$articleId);
//        var_dump('$learnMeans:'.$learnMeans);
        Db::startTrans();
        try {
            $LearnReadingArticleModel = new LearnReadingArticle();
            // 如果有上课记录ID，检查是否存在未提交的答题记录
            if ($skRecordId) {
                // 查询是否存在未提交的答题记录
                $lastReadingArticleId = $LearnReadingArticleModel->where('skRecordId', $skRecordId)
                    ->where('articleId', $articleId)
                    ->where('isSubmit', 0)
                    ->order('id', 'asc')
                    ->limit(1)
                    ->value('id');
                // 如果存在未提交的记录，直接返回该记录ID
                if ($lastReadingArticleId) {
                    return $lastReadingArticleId;
                }
            }

            // 查询文章信息
            $CourseArticleModel = new CourseArticle();
            $courseArticle = $CourseArticleModel->where('id', $articleId)->find();

            // 验证文章是否存在
            if (empty($courseArticle)) {
                throw new Exception('文章不存在');
            }

            // 验证文章是否已发布（启用状态）
            if ($courseArticle['status'] != ArticleStatusEnum::E1) {  // 1 对应 ArticleStatus.E1 启用状态
                throw new Exception('文章未发布');
            }

            // 获取学生组织ID
            $studentOrgId = null;
            if ($studentId) {
                $student = Student::where('id', $studentId)->find();

                // 验证学生是否存在
                if (empty($student)) {
                    throw new Exception('学员不存在');
                }

                $studentOrgId = $student['organizationId'];
            }

            // 查询文章相关题目
            $questionList = CourseQuestion::where('dataId', $articleId)
                ->where('dataType', CourseDataTypeEnum::ARTICLE)  // 1 对应 CourseDataType.ARTICLE 文章类型
                ->order('sortNum', 'asc')
                ->select();

            // 验证文章是否有题目
            if (empty($questionList)) {
                throw new Exception('文章没有题目，无法作答，请更换文章');
            }

            // 获取课程ID
            $courseId = $courseArticle['courseId'];

            // 创建阅读记录
            $learnReadingArticleData = [
                'skRecordId' => $skRecordId,
                'studentId' => $studentId,
                'studentOrgId' => $studentOrgId,
                'actualCourseId' => $courseId,
                'trainerId' => $trainerId,
                'articleId' => $articleId,
                'articleName' => $courseArticle['name'],
                'startTime' => date('Y-m-d H:i:s'),
                'learnMeans' => $learnMeans,  // 1-教学，2-练习
                'limitAnswer' => $courseArticle['limitAnswer'],
                'readingType' => ReadingTypeEnum::READING,  // 1 对应 ReadingType.READING 阅读类型
                'createTime' => time(),
                'updateTime' => time()
            ];

            // 保存开始阅读记录
            $readingArticleId = $LearnReadingArticleModel->insertGetId($learnReadingArticleData);

            // 保存扩展记录
            $readingArticleExtendData = [
                'readingArticleId' => $readingArticleId,
                'difficulty' => $courseArticle['difficulty'],
                'helpfulDuration' => $courseArticle['helpfulDuration'],
                'articleTitle' => $courseArticle['name'],
                'articleContent' => $courseArticle['content'],
                'articleContentCn' => $courseArticle['contentCn'],
                'articleContentVoice' => $courseArticle['contentVoice'],
                'createTime' => time(),
                'updateTime' => time()
            ];
            $LearnReadingArticleExtendModel = new LearnReadingArticleExtend();
            $LearnReadingArticleExtendModel->insert($readingArticleExtendData);

            // 保存题目信息
            $readingArticleAnswerDataList = [];
            foreach ($questionList as $question) {
                $readingArticleAnswerDataList[] = [
                    'readingArticleId' => $readingArticleId,
                    'studentId' => $studentId,
                    'courseId' => $courseId,
                    'articleId' => $articleId,
                    'questionId' => $question['id'],
                    'questionName' => $question['name'],
                    'questionType' => $question['questionType'],
                    'option' => $question['option'],
                    'answer' => $question['answer'],
                    'analysis' => $question['analysis'],
                    'createTime' => time(),
                    'updateTime' => time()
                ];
            }
            // 批量保存题目信息
            if (!empty($readingArticleAnswerDataList)) {
                $LearnReadingArticleAnswerModel = new LearnReadingArticleAnswer();
                $LearnReadingArticleAnswerModel->insertAll($readingArticleAnswerDataList);
            }


            Db::commit();
            return $readingArticleId;
        } catch (Exception|PDOException|ValidateException $e) {
            Db::rollback();
            $this->setError($e->getMessage());
            return false;
        }
    }

    /**
     * 答题
     * @param int $readingArticleId 阅读文章ID
     * @param int|null $trainerId 教练ID
     * @param int|null $studentId 学生ID
     * @param int $useTime 使用时间（秒）
     * @param array|null $answerList 答案列表
     * @throws Exception
     */
    public function answerQuestion($readingArticleId, $trainerId, $studentId, $useTime, $answerList)
    {
        Db::startTrans();
        try {
            // 查询阅读记录
            $LearnReadingArticleModel = new LearnReadingArticle();
            $readingArticle = $LearnReadingArticleModel
                ->where('id', $readingArticleId)
                ->find();

            // 验证阅读记录是否存在
            if (empty($readingArticle)) {
                throw new Exception('阅读记录不存在');
            }

            // 如果提供了教练ID，验证教练权限
            if ($trainerId) {
                if ($readingArticle['trainerId'] != $trainerId) {
                    throw new Exception('阅读记录不存在');
                }
            }

            // 如果提供了学生ID，验证学生权限
            if ($studentId) {
                if ($readingArticle['studentId'] != $studentId) {
                    throw new Exception('阅读记录不存在');
                }
            }

            $skRecordId = $readingArticle['skRecordId'];

            // 上课-阅读记录
            $learnReading = null;
            $learnSkRecord = null;

            // 如果有上课记录ID
            $LearnSkRecordModel = new LearnSkRecord();
            $LearnReadingModel = new LearnReading();
            if ($skRecordId) {
                // 查询上课记录
                $learnSkRecord = $LearnSkRecordModel->where('id', $skRecordId)->find();

                // 验证上课记录是否存在
                if (empty($learnSkRecord)) {
                    throw new Exception('上课记录不存在');
                }

                // 查询阅读记录

                $learnReading = $LearnReadingModel
                    ->where('skRecordId', $skRecordId)
                    ->where('courseId', $learnSkRecord['courseId'])
                    ->find();
            }

            // 检查答题次数限制
            if ($learnSkRecord  && $readingArticle['limitAnswer'] > 0) {
                $articleId = $readingArticle['articleId'];

                // 查询当前答题次数
                $currentNum = $LearnReadingArticleModel
                    ->where('skRecordId', $skRecordId)
                    ->where('articleId', $articleId)
                    ->where('readingType', 2) // 2 对应 ReadingType.READING 阅读理解
                    ->where('isSubmit', 1)
                    ->count();

                // 验证是否超过答题次数限制
                if ($currentNum >= $readingArticle['limitAnswer']) {
                    throw new Exception('答题次数已达上限，本次上课内不可再次重复答题');
                }
            }

            // 准备提交题目
            $LearnReadingArticleAnswerModel = new LearnReadingArticleAnswer();
            $readingArticleAnswerList = $LearnReadingArticleAnswerModel->where('readingArticleId', $readingArticleId)->select();

            // 验证题目是否存在
            if (empty($readingArticleAnswerList)) {
                throw new Exception('提交失败，当前阅读无题目');
            }

            $updateReadingArticleAnswerList = [];

            // 处理每个题目答案
            foreach ($readingArticleAnswerList as $it) {
                $result = null;

                // 在用户答案中查找对应题目的答案
                if (!empty($answerList)) {
                    foreach ($answerList as $answer) {
                        if (isset($answer['id']) && $answer['id'] == $it['id']) {
                            $result = $answer;
                            break;
                        }
                    }
                }

                // 判断题目是否正确
                $isCorrect = false;
                $userAnswerList = [];

                if ($result !== null) {
                    $questionType = $it['questionType'];
                    $userAnswerList = isset($result['userAnswerList']) ? $result['userAnswerList'] : [];

                    // 移除空字符串
                    $userAnswerList = array_filter($userAnswerList, function($value) {
                        return trim($value) !== '';
                    });

                    // 根据题目类型判断答案是否正确
                    switch ($questionType) {
                        case 1: // 1 对应 QuestionType.E1 单选
                            $answerListArray = json_decode($it['answer'], true);
                            if (!is_array($answerListArray)) {
                                $answerListArray = [$it['answer']];
                            }

                            $isCorrect = count($userAnswerList) == 1 && in_array($userAnswerList[0], $answerListArray);
                            break;

                        case 2: // 2 对应 QuestionType.E2 多选
                            if (!empty($userAnswerList)) {
                                $answerListArray = json_decode($it['answer'], true);
                                if (!is_array($answerListArray)) {
                                    $answerListArray = [$it['answer']];
                                }

                                // 检查用户答案是否包含所有正确答案
                                $isCorrect = !empty(array_diff($answerListArray, $userAnswerList)) === false
                                    && !empty(array_diff($userAnswerList, $answerListArray)) === false;
                            }
                            break;
                    }
                }

                // 构造更新数据
                $updateReadingArticleAnswerList[] = [
                    'id' => $it['id'],
                    'isCorrect' => $isCorrect,
                    'userAnswer' => json_encode($userAnswerList, JSON_UNESCAPED_UNICODE)
                ];
            }

            // 更新统计信息
            $totalNum = count($updateReadingArticleAnswerList);
            $correctNum = 0;

            // 统计正确题目数量
            foreach ($updateReadingArticleAnswerList as $answer) {
                if ($answer['isCorrect']) {
                    $correctNum++;
                }
            }

            $errorNum = $totalNum - $correctNum;
            $correctRate = $totalNum > 0 ? intval($correctNum * 100 / $totalNum) : 0;

            // 构造更新数据
            $updateReadingArticle = [
                'totalNum' => $totalNum,
                'correctNum' => $correctNum,
                'errorNum' => $errorNum,
                'correctRate' => $correctRate,
                'startTime' => date('Y-m-d H:i:s', strtotime("-{$useTime} seconds")),
                'endTime' => date('Y-m-d H:i:s'),
                'useTime' => $useTime,
                'isSubmit' => 1,
                'updateTime' => time()
            ];

            // 更新阅读文章记录
            $cnt = $LearnReadingArticleModel
                ->update($updateReadingArticle,['id'=>$readingArticleId]);

            if (!$cnt) {
                throw new Exception('提交失败，请稍后重试');
            }

            // 更新答题答案
            foreach ($updateReadingArticleAnswerList as $answer) {
                $LearnReadingArticleAnswerModel
                    ->update([
                        'isCorrect' => $answer['isCorrect'],
                        'userAnswer' => $answer['userAnswer'],
                        'updateTime' => time()
                    ],['id'=>$answer['id']]);
            }

            // 上课-阅读记录逻辑
            if ($learnSkRecord !== null) {
                $courseId = $learnSkRecord['courseId'];

                // 如果阅读记录不存在，则创建新的
                if (empty($learnReading)) {
                    $learnReadingData = [
                        'skRecordId' => $skRecordId,
                        'courseId' => $courseId,
                        'courseName' => $learnSkRecord['courseName'],
                        'studentId' => $learnSkRecord['studentId'],
                        'studentOrgId' => $learnSkRecord['studentOrgId'],
                        'trainerId' => $learnSkRecord['trainerId'],
                        'courseFullType' => $learnSkRecord['courseFullType'],
                        'courseDeliveryType' => $learnSkRecord['courseDeliveryType'],
                        'actualStartTime' => $learnSkRecord['actualStartTime'],
                        'createTime' => time(),
                        'updateTime' => time()
                    ];

                    $LearnReadingModel->create($learnReadingData);
                }
            }
            Db::commit();
            return true;
        } catch (Exception|PDOException|ValidateException $e) {
            Db::rollback();
            $this->setError($e->getMessage());
            return false;
        }
    }
}